package session.TX;

import Helper.TTAHelper.Helper_DishSale;
import Helper.TTAHelper.Helper_MDSCluster;
import Helper.TTAHelper.Helper_PIPResPred;
import Helper.TTAHelper.Helper_PIPReservation;
import Helper.TTAHelper.Helper_PIPSales;
import Helper.TTAHelper.Helper_PIPSalesPred;
import Helper.TTAHelper.Helper_ReservationByAge;
import Helper.TTAHelper.Helper_ReservationByCountry;
import Helper.TTAHelper.Helper_SalesByAge;
import Helper.TTAHelper.Helper_SalesByCountry;
import entity.FoodItem;
import entity.Outlet;
import entity.Stakeholder;
import entity.tta.OutletDataModel;
import entity.tta.StakeholderDataModel;
import entity.tta.StrDblRecord;
import entity.tta.StrLongRecord;
import entity.tta.TCubeDataModel;
import flanagan.analysis.Regression;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author Lu Xiaodi
 */
@Stateless
public class TTADisplaySB implements TTADisplaySBRemote {

    @PersistenceContext
    EntityManager em;
    public static final Calendar TCubeCreationTime = generateTCubeCreateTime();
    
    public static Calendar generateTCubeCreateTime() {
        Calendar time = Calendar.getInstance();
        time.set(2009, 7, 1, 0, 0, 0);
        return time;
    }

    //=========================Test Methods Begin==================================
    public void printReg_Test() {
        double[] x = new double[10];
        double[] y = new double[10];
        for (int i = 0; i < 10; i++) {
            x[i] = (double) (i);
            y[i] = i * 2 + 1;
        }
        Regression reg = new Regression(x, y);
        reg.linear();
        double[] result = reg.getCoeff();
//        for (int j = 0; j < result.length; j++) {
//            System.out.println(result[j]);
//        }
    }
    //=========================Test Methods end====================================

    //=========================PIP Methods begin====================================
    public Helper_PIPSalesPred getSalesDataWithPred(Long outletId, Calendar s, Calendar e, int numMonthPred) {
        List<Helper_PIPSales> sales = this.getOSalesData(outletId, s, e);
        if (sales == null || sales.size() <= 1) {
            return new Helper_PIPSalesPred();
        }
        List<Helper_PIPSales> modelList = new ArrayList<Helper_PIPSales>();
        modelList.addAll(sales);
        double[] coef = this.getSalesRegCoef(sales);
        double corcoef = this.getSalesRegCorCoef(sales);
        Calendar predMonth = (Calendar) e.clone();
        for (int i = 1; i <= numMonthPred; i++) {
            int x = sales.size() + i;
            double y = coef[0] + coef[1] * x;
            predMonth.add(Calendar.MONTH, 1);
            modelList.add(new Helper_PIPSales((Calendar) predMonth.clone(), y));
        }
        return new Helper_PIPSalesPred(modelList, corcoef);
    }

    public Helper_PIPResPred getResDataWithPred(Long outletId, Calendar s, Calendar e, int numMonthPred) {
        List<Helper_PIPReservation> res = this.getOReservationData(outletId, s, e);
        if (res == null || res.size() <= 1) {
            return new Helper_PIPResPred();
        }
        List<Helper_PIPReservation> modelList = new ArrayList<Helper_PIPReservation>();
        modelList.addAll(res);
        double[] coef = this.getResRegCoef(res);
        double corcoef = this.getResRegCorCoef(res);
        Calendar predMonth = (Calendar) e.clone();
        for (int i = 1; i <= numMonthPred; i++) {
            int x = res.size() + i;
            long y = Math.round(coef[0] + coef[1] * x);
            predMonth.add(Calendar.MONTH, 1);
            modelList.add(new Helper_PIPReservation((Calendar) predMonth.clone(), y));
        }
        return new Helper_PIPResPred(modelList, corcoef);
    }
    
    public Helper_PIPSalesPred getSalesDataWithPred(String stakeholderName, Calendar s,
            Calendar e, int numMonthPred) {
        List<Helper_PIPSales> sales = this.getSSalesData(stakeholderName, s, e);
        if (sales == null || sales.size() <= 1) {
            return new Helper_PIPSalesPred();
        }
        List<Helper_PIPSales> modelList = new ArrayList<Helper_PIPSales>();
        modelList.addAll(sales);
        double[] coef = this.getSalesRegCoef(sales);
        double corcoef = this.getSalesRegCorCoef(sales);
        Calendar predMonth = (Calendar) e.clone();
        for (int i = 1; i <= numMonthPred; i++) {
            int x = sales.size() + i;
            double y = coef[0] + coef[1] * x;
            predMonth.add(Calendar.MONTH, 1);
            modelList.add(new Helper_PIPSales((Calendar) predMonth.clone(), y));
        }
        return new Helper_PIPSalesPred(modelList, corcoef);
    }

    public Helper_PIPResPred getResDataWithPred(String stakeholderName, Calendar s,
            Calendar e, int numMonthPred) {
        List<Helper_PIPReservation> res = this.getSReservationData(stakeholderName, s, e);
        if (res == null || res.size() <= 1) {
            return new Helper_PIPResPred();
        }
        List<Helper_PIPReservation> modelList = new ArrayList<Helper_PIPReservation>();
        modelList.addAll(res);
        double[] coef = this.getResRegCoef(res);
        double corcoef = this.getResRegCorCoef(res);
        Calendar predMonth = (Calendar) e.clone();
        for (int i = 1; i <= numMonthPred; i++) {
            int x = res.size() + i;
            long y = Math.round(coef[0] + coef[1] * x);
            predMonth.add(Calendar.MONTH, 1);
            modelList.add(new Helper_PIPReservation((Calendar) predMonth.clone(), y));
        }
        return new Helper_PIPResPred(modelList, corcoef);
    }
    
    public Helper_PIPSalesPred getSalesDataWithPred(Calendar s,
            Calendar e, int numMonthPred) {
        List<Helper_PIPSales> sales = this.getTCubeSalesData(s, e);
        if (sales == null || sales.size() <= 1) {
            return new Helper_PIPSalesPred();
        }
        List<Helper_PIPSales> modelList = new ArrayList<Helper_PIPSales>();
        modelList.addAll(sales);
        double[] coef = this.getSalesRegCoef(sales);
        double corcoef = this.getSalesRegCorCoef(sales);
        Calendar predMonth = (Calendar) e.clone();
        for (int i = 1; i <= numMonthPred; i++) {
            int x = sales.size() + i;
            double y = coef[0] + coef[1] * x;
            predMonth.add(Calendar.MONTH, 1);
            modelList.add(new Helper_PIPSales((Calendar) predMonth.clone(), y));
        }
        return new Helper_PIPSalesPred(modelList, corcoef);
    }

    public Helper_PIPResPred getResDataWithPred(Calendar s,
            Calendar e, int numMonthPred) {
        List<Helper_PIPReservation> res = this.getTCubeReservationData(s, e);
        if (res == null || res.size() <= 1) {
            return new Helper_PIPResPred();
        }
        List<Helper_PIPReservation> modelList = new ArrayList<Helper_PIPReservation>();
        modelList.addAll(res);
        double[] coef = this.getResRegCoef(res);
        double corcoef = this.getResRegCorCoef(res);
        Calendar predMonth = (Calendar) e.clone();
        for (int i = 1; i <= numMonthPred; i++) {
            int x = res.size() + i;
            long y = Math.round(coef[0] + coef[1] * x);
            predMonth.add(Calendar.MONTH, 1);
            modelList.add(new Helper_PIPReservation((Calendar) predMonth.clone(), y));
        }
        return new Helper_PIPResPred(modelList, corcoef);
    }
    
    //result[0] = intercept
    //result[1] = coefficient
    private double[] getSalesRegCoef(List<Helper_PIPSales> input) {
        double[] x = new double[input.size()];
        double[] y = new double[input.size()];
        for (int i = 0; i < input.size(); i++) {
            x[i] = (double) (i);
            y[i] = input.get(i).getRevenue();
        }
        Regression reg = new Regression(x, y);
        reg.linear();
        double[] result = reg.getCoeff();
        return result;
    }

    //return[0] = intercept
    //return[1] = coefficient
    private double[] getResRegCoef(List<Helper_PIPReservation> input) {
        double[] x = new double[input.size()];
        double[] y = new double[input.size()];
        for (int i = 0; i < input.size(); i++) {
            x[i] = (double) (i);
            y[i] = input.get(i).getNumReservations();
        }
        Regression reg = new Regression(x, y);
        reg.linear();
        double[] result = reg.getCoeff();
        return result;
    }
    
    //get sales correlation coefficient
    private double getSalesRegCorCoef(List<Helper_PIPSales> input){
        double[] x = new double[input.size()];
        double[] y = new double[input.size()];
        for (int i = 0; i < input.size(); i++) {
            x[i] = (double) (i);
            y[i] = input.get(i).getRevenue();
        }
        Regression reg = new Regression(x, y);
        reg.linear();
        double result = reg.getXYcorrCoeff();
        return result;
    }
    
    //get reservation correlation coefficient
    private double getResRegCorCoef(List<Helper_PIPReservation> input) {
        double[] x = new double[input.size()];
        double[] y = new double[input.size()];
        for (int i = 0; i < input.size(); i++) {
            x[i] = (double) (i);
            y[i] = input.get(i).getNumReservations();
        }
        Regression reg = new Regression(x, y);
        reg.linear();
        double result = reg.getXYcorrCoeff();
        return result;
    }

    public List<Helper_PIPSales> getOSalesData(Long outletId, Calendar s, Calendar e) {
        System.out.println("getting sales data..");
        Calendar start = (Calendar) s.clone();
        Calendar end = (Calendar) e.clone();
        System.out.println("s:" + s.get(Calendar.YEAR) + "," + s.get(Calendar.MONTH));
        System.out.println("e:" + e.get(Calendar.YEAR) + "," + e.get(Calendar.MONTH));
        Query query = em.createQuery("SELECT odm FROM OutletDataModel odm WHERE odm.outletId = :outletId");
        query.setParameter("outletId", outletId);
        List<OutletDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        OutletDataModel dataModel = resultList.get(0);

        List<StrDblRecord> allRecords = dataModel.getStrDblRecords();
        List<Helper_PIPSales> returnList = new ArrayList<Helper_PIPSales>();
        Calendar idx = (Calendar) start.clone();

        while (!idx.after(end)) {
            idx.add(Calendar.MONTH, 1);
            String attribute = idx.get(Calendar.YEAR) + "-" + idx.get(Calendar.MONTH);
            idx.add(Calendar.MONTH, -1);
            for (StrDblRecord aRecord : allRecords) {
                if (aRecord.getAttribute().equalsIgnoreCase(attribute)
                        && aRecord.getType().equalsIgnoreCase("O_" + outletId + "MonthSale")) {
//                    Helper_PIPSales aHelper = new Helper_PIPSales(idx, aRecord.getNumDouble());
                    Helper_PIPSales aHelper = new Helper_PIPSales((Calendar) idx.clone(), aRecord.getNumDouble());
                    returnList.add(aHelper);
                }
            }
            idx.add(Calendar.MONTH, 1);
        }
        System.out.println("getosalesdata returnlist size: " + returnList.size());
        System.out.println("getting sales data finished~");
        return returnList;
    }

    public List<Helper_PIPReservation> getOReservationData(Long outletId, Calendar s, Calendar e) {
        System.out.println("getting reservation data..");
        System.out.println("s:" + s.get(Calendar.YEAR) + "," + s.get(Calendar.MONTH));
        System.out.println("e:" + e.get(Calendar.YEAR) + "," + e.get(Calendar.MONTH));
        Calendar start = (Calendar) s.clone();
        Calendar end = (Calendar) e.clone();
        Query query = em.createQuery("SELECT odm FROM OutletDataModel odm WHERE odm.outletId = :outletId");
        query.setParameter("outletId", outletId);
        List<OutletDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        OutletDataModel dataModel = resultList.get(0);

        List<StrLongRecord> allRecords = dataModel.getStrLongRecords();
        List<Helper_PIPReservation> returnList = new ArrayList<Helper_PIPReservation>();
        Calendar idx = (Calendar) start.clone();

        while (!idx.after(end)) {
            idx.add(Calendar.MONTH, 1);
            String attribute = idx.get(Calendar.YEAR) + "-" + idx.get(Calendar.MONTH);
            idx.add(Calendar.MONTH, -1);
            for (StrLongRecord aRecord : allRecords) {
                if (aRecord.getAttribute().equalsIgnoreCase(attribute)
                        && aRecord.getType().equalsIgnoreCase("O_" + outletId + "MonthReservation")) {
//                    Helper_PIPSales aHelper = new Helper_PIPSales(idx, aRecord.getNumDouble());
                    Helper_PIPReservation aHelper = new Helper_PIPReservation((Calendar) idx.clone(),
                            aRecord.getNumberLong());
                    returnList.add(aHelper);
                }
            }
            idx.add(Calendar.MONTH, 1);
        }
        System.out.println("getting reservation data finished~");
        return returnList;
    }

    public List<Helper_PIPSales> getSSalesData(String stakeholderName, Calendar s, Calendar e) {
        System.out.println("getting sales data..");
        Calendar start = (Calendar) s.clone();
        Calendar end = (Calendar) e.clone();
        Query query = em.createQuery("SELECT sdm FROM StakeholderDataModel sdm WHERE sdm.stakeholderName = :sName");
        query.setParameter("sName", stakeholderName);
        List<StakeholderDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        StakeholderDataModel dataModel = resultList.get(0);

        List<StrDblRecord> allRecords = dataModel.getStrDblRecords();
        List<Helper_PIPSales> returnList = new ArrayList<Helper_PIPSales>();
        Calendar idx = (Calendar) start.clone();

        while (!idx.after(end)) {
            idx.add(Calendar.MONTH, 1);
            String attribute = idx.get(Calendar.YEAR) + "-" + idx.get(Calendar.MONTH);
            idx.add(Calendar.MONTH, -1);
            for (StrDblRecord aRecord : allRecords) {
                if (aRecord.getAttribute().equalsIgnoreCase(attribute)
                        && aRecord.getType().equalsIgnoreCase("S_" + stakeholderName + "MonthSale")) {
//                    Helper_PIPSales aHelper = new Helper_PIPSales(idx, aRecord.getNumDouble());
                    Helper_PIPSales aHelper = new Helper_PIPSales((Calendar) idx.clone(), aRecord.getNumDouble());
                    returnList.add(aHelper);
                }
            }
            idx.add(Calendar.MONTH, 1);
        }
        System.out.println("getting sales data finished~");
        return returnList;
    }

    public List<Helper_PIPReservation> getSReservationData(String stakeholderName, Calendar s, Calendar e) {
        System.out.println("getting reservation data..");
        System.out.println("s:" + s.get(Calendar.YEAR) + "," + s.get(Calendar.MONTH));
        System.out.println("e:" + e.get(Calendar.YEAR) + "," + e.get(Calendar.MONTH));
        Calendar start = (Calendar) s.clone();
        Calendar end = (Calendar) e.clone();
        Query query = em.createQuery("SELECT sdm FROM StakeholderDataModel sdm WHERE sdm.stakeholderName = :sName");
        query.setParameter("sName", stakeholderName);
        List<StakeholderDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        StakeholderDataModel dataModel = resultList.get(0);

        List<StrLongRecord> allRecords = dataModel.getStrLongRecords();
        List<Helper_PIPReservation> returnList = new ArrayList<Helper_PIPReservation>();
        Calendar idx = (Calendar) start.clone();

        while (!idx.after(end)) {
            idx.add(Calendar.MONTH, 1);
            String attribute = idx.get(Calendar.YEAR) + "-" + idx.get(Calendar.MONTH);
            idx.add(Calendar.MONTH, -1);
            for (StrLongRecord aRecord : allRecords) {
                if (aRecord.getAttribute().equalsIgnoreCase(attribute)
                        && aRecord.getType().equalsIgnoreCase("S_" + stakeholderName + "MonthReservation")) {
//                    Helper_PIPSales aHelper = new Helper_PIPSales(idx, aRecord.getNumDouble());
                    Helper_PIPReservation aHelper = new Helper_PIPReservation((Calendar) idx.clone(),
                            aRecord.getNumberLong());
                    returnList.add(aHelper);
                }
            }
            idx.add(Calendar.MONTH, 1);
        }
        System.out.println("getting reservation data finished~");
        return returnList;
    }

    public List<Helper_PIPSales> getTCubeSalesData(Calendar s, Calendar e) {
        System.out.println("getting sales data..");
        Calendar start = (Calendar) s.clone();
        Calendar end = (Calendar) e.clone();
        Query query = em.createQuery("SELECT tdm FROM TCubeDataModel tdm");
        List<TCubeDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        TCubeDataModel dataModel = resultList.get(0);

        List<StrDblRecord> allRecords = dataModel.getStrDblRecords();
        List<Helper_PIPSales> returnList = new ArrayList<Helper_PIPSales>();
        Calendar idx = (Calendar) start.clone();

        while (!idx.after(end)) {
            idx.add(Calendar.MONTH, 1);
            String attribute = idx.get(Calendar.YEAR) + "-" + idx.get(Calendar.MONTH);
            idx.add(Calendar.MONTH, -1);
            for (StrDblRecord aRecord : allRecords) {
                if (aRecord.getAttribute().equalsIgnoreCase(attribute)
                        && aRecord.getType().equalsIgnoreCase("T_MonthSale")) {
//                    Helper_PIPSales aHelper = new Helper_PIPSales(idx, aRecord.getNumDouble());
                    Helper_PIPSales aHelper = new Helper_PIPSales((Calendar) idx.clone(), aRecord.getNumDouble());
                    returnList.add(aHelper);
                }
            }
            idx.add(Calendar.MONTH, 1);
        }
        System.out.println("getosalesdata returnlist size: " + returnList.size());
        System.out.println("getting sales data finished~");
        return returnList;
    }

    public List<Helper_PIPReservation> getTCubeReservationData(Calendar s, Calendar e) {
        System.out.println("getting reservation data..");
        Calendar start = (Calendar) s.clone();
        Calendar end = (Calendar) e.clone();
        Query query = em.createQuery("SELECT tdm FROM TCubeDataModel tdm ");
        List<TCubeDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        TCubeDataModel dataModel = resultList.get(0);

        List<StrLongRecord> allRecords = dataModel.getStrLongRecords();
        List<Helper_PIPReservation> returnList = new ArrayList<Helper_PIPReservation>();
        Calendar idx = (Calendar) start.clone();

        while (!idx.after(end)) {
            idx.add(Calendar.MONTH, 1);
            String attribute = idx.get(Calendar.YEAR) + "-" + idx.get(Calendar.MONTH);
            idx.add(Calendar.MONTH, -1);
            for (StrLongRecord aRecord : allRecords) {
                if (aRecord.getAttribute().equalsIgnoreCase(attribute)
                        && aRecord.getType().equalsIgnoreCase("T_MonthReservation")) {
//                    Helper_PIPSales aHelper = new Helper_PIPSales(idx, aRecord.getNumDouble());
                    Helper_PIPReservation aHelper = new Helper_PIPReservation((Calendar) idx.clone(),
                            aRecord.getNumberLong());
                    returnList.add(aHelper);
                }
            }
            idx.add(Calendar.MONTH, 1);
        }
        System.out.println("getting reservation data finished~");
        return returnList;
    }

    public List<Calendar> getOAvailableMonths(Long outletId) {
        Calendar cEnd = Calendar.getInstance();
        cEnd.setTime(new Date());
        cEnd.set(cEnd.get(Calendar.YEAR), cEnd.get(Calendar.MONTH), 1, 0, 0, 0);

        //get respected outlet data model
        Outlet o = em.find(Outlet.class, outletId);
        if (o == null) {
            return null;
        }

        // if o != null, set cBegin to the creation time of the odm 
        Calendar cBegin = (Calendar) o.getCreateTime().clone();

        List<Calendar> list = new ArrayList<Calendar>();
        while (cBegin.before(cEnd)) {
            list.add((Calendar) cBegin.clone());
            cBegin.add(Calendar.MONTH, 1);
        }

//        for (Calendar c : list) {
//            System.out.println("year:" + c.get(Calendar.YEAR) + "; month:" + c.get(Calendar.MONTH));
//        }

        return list;
    }

    public List<Calendar> getSAvailableMonths(String stakeholderName) {
        Calendar cEnd = Calendar.getInstance();
        cEnd.setTime(new Date());
        cEnd.set(cEnd.get(Calendar.YEAR), cEnd.get(Calendar.MONTH), 1, 0, 0, 0);

        //get respected outlet data model
        Query q = em.createQuery("SELECT s FROM Stakeholder s WHERE s.name = :sName");
        q.setParameter("sName", stakeholderName);
        List<Stakeholder> result = q.getResultList();
        if (result == null || result.isEmpty()) {
            return null;
        }
        Stakeholder s = result.get(0);

        // if o != null, set cBegin to the creation time of the odm
        Calendar cBegin = (Calendar) s.getCreateTime().clone();
        List<Calendar> list = new ArrayList<Calendar>();
        while (cBegin.before(cEnd)) {
            list.add((Calendar) cBegin.clone());
            cBegin.add(Calendar.MONTH, 1);
        }

//        for (Calendar c : list) {
//            System.out.println("year:" + c.get(Calendar.YEAR) + "; month:" + c.get(Calendar.MONTH));
//        }

        return list;
    }

    public List<Calendar> getTCubeAvailableMonths() {
        Calendar cEnd = Calendar.getInstance();
        cEnd.setTime(new Date());
        cEnd.set(cEnd.get(Calendar.YEAR), cEnd.get(Calendar.MONTH), 1, 0, 0, 0);

        // if o != null, set cBegin to the creation time of the odm
        Calendar cBegin = (Calendar) TCubeCreationTime.clone();
        List<Calendar> list = new ArrayList<Calendar>();
        while (cBegin.before(cEnd)) {
            list.add((Calendar) cBegin.clone());
            cBegin.add(Calendar.MONTH, 1);
        }
        return list;
    }
    //==========================PIP Methods end=====================================

    //=========================MDS Methods begin====================================
    public List<Helper_SalesByAge> getOSalesByAge(Long outletId, Integer withinTime) {
        Query query = em.createQuery("SELECT odm FROM OutletDataModel odm WHERE odm.outletId = :outletId");
        query.setParameter("outletId", outletId);
        List<OutletDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        OutletDataModel dataModel = resultList.get(0);

        List<StrDblRecord> strDblRecords = dataModel.getStrDblRecords();
        List<Helper_SalesByAge> returnList = new ArrayList<Helper_SalesByAge>();
        for (StrDblRecord r : strDblRecords) {
            if (r.getType().trim().equalsIgnoreCase("O_" + outletId + "SaleAgeGroupW" + withinTime + "M")) {
                returnList.add(new Helper_SalesByAge(r.getNumDouble(), r.getAttribute().trim()));
            }
        }
        return returnList;
    }

    public List<Helper_SalesByCountry> getOSalesByCountry(Long outletId, Integer withinTime) {
        Query query = em.createQuery("SELECT odm FROM OutletDataModel odm WHERE odm.outletId = :outletId");
        query.setParameter("outletId", outletId);
        List<OutletDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        OutletDataModel dataModel = resultList.get(0);

        List<StrDblRecord> strDblRecords = dataModel.getStrDblRecords();
        List<Helper_SalesByCountry> returnList = new ArrayList<Helper_SalesByCountry>();
        for (StrDblRecord r : strDblRecords) {
            if (r.getType().trim().equalsIgnoreCase("O_" + outletId + "SaleCountryW" + withinTime + "M")) {
                returnList.add(new Helper_SalesByCountry(r.getNumDouble(), r.getAttribute().trim()));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }

    public List<Helper_ReservationByAge> getOReservationByAge(Long outletId, Integer withinTime) {
        Query query = em.createQuery("SELECT odm FROM OutletDataModel odm WHERE odm.outletId = :outletId");
        query.setParameter("outletId", outletId);
        List<OutletDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        OutletDataModel dataModel = resultList.get(0);

        List<StrLongRecord> strLongRecords = dataModel.getStrLongRecords();
        List<Helper_ReservationByAge> returnList = new ArrayList<Helper_ReservationByAge>();
        for (StrLongRecord r : strLongRecords) {
            if (r.getType().trim().equalsIgnoreCase("O_" + outletId + "ReservationAgeGroupW" + withinTime + "M")) {
                returnList.add(new Helper_ReservationByAge(r.getNumberLong(), r.getAttribute().trim()));
            }
        }
        return returnList;
    }

    public List<Helper_ReservationByCountry> getOReservationByCountry(Long outletId, Integer withinTime) {
        Query query = em.createQuery("SELECT odm FROM OutletDataModel odm WHERE odm.outletId = :outletId");
        query.setParameter("outletId", outletId);
        List<OutletDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        OutletDataModel dataModel = resultList.get(0);

        List<StrLongRecord> strLongRecords = dataModel.getStrLongRecords();
        List<Helper_ReservationByCountry> returnList = new ArrayList<Helper_ReservationByCountry>();
        for (StrLongRecord r : strLongRecords) {
            if (r.getType().trim().equalsIgnoreCase("O_" + outletId + "ReservationCountryW" + withinTime + "M")) {
                returnList.add(new Helper_ReservationByCountry(r.getNumberLong(), r.getAttribute().trim()));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }

    public List<Helper_MDSCluster> getOAllClusters(Long outletId) {
        Query query = em.createQuery("SELECT odm FROM OutletDataModel odm WHERE odm.outletId = :outletId");
        query.setParameter("outletId", outletId);
        List<OutletDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        OutletDataModel dataModel = resultList.get(0);
        Long[][] cluster = dataModel.getCluster();
        List<Helper_MDSCluster> returnList = new ArrayList<Helper_MDSCluster>();
        String[] countriesArray = dataModel.getCountriesArray();
        String[] ageGroupArray = dataModel.getAgeGroupsArray();
        for (int r = 0; r < cluster.length; r++) {
            for (int c = 0; c < cluster[0].length; c++) {
                returnList.add(new Helper_MDSCluster(countriesArray[r], ageGroupArray[c], cluster[r][c]));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }

    public List<Helper_MDSCluster> getOAllClustersW2Y(Long outletId) {
        Query query = em.createQuery("SELECT odm FROM OutletDataModel odm WHERE odm.outletId = :outletId");
        query.setParameter("outletId", outletId);
        List<OutletDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        OutletDataModel dataModel = resultList.get(0);
        Long[][] cluster = dataModel.getClusterW2Y();
        List<Helper_MDSCluster> returnList = new ArrayList<Helper_MDSCluster>();
        String[] countriesArray = dataModel.getCountriesArray();
        String[] ageGroupArray = dataModel.getAgeGroupsArray();
        for (int r = 0; r < cluster.length; r++) {
            for (int c = 0; c < cluster[0].length; c++) {
                returnList.add(new Helper_MDSCluster(countriesArray[r], ageGroupArray[c], cluster[r][c]));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }

    public List<Helper_DishSale> getODishSale(Long outletId, Integer withinTime) {
        Query query = em.createQuery("SELECT odm FROM OutletDataModel odm WHERE odm.outletId = :outletId");
        query.setParameter("outletId", outletId);
        List<OutletDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        OutletDataModel dataModel = resultList.get(0);
        List<StrLongRecord> allStrLongs = dataModel.getStrLongRecords();
        List<Helper_DishSale> returnList = new ArrayList<Helper_DishSale>();
        for (StrLongRecord aRecord : allStrLongs) {
            if (aRecord.getType().trim().equalsIgnoreCase("O_" + outletId + "DishSaleW" + withinTime + "M")) {
                Long dishId = Long.parseLong(aRecord.getAttribute().trim());
                FoodItem dishItem = em.find(FoodItem.class, dishId);
                returnList.add(new Helper_DishSale(dishItem.getId(), dishItem.getName(), aRecord.getNumberLong()));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }

    public List<Helper_SalesByAge> getSSalesByAge(String stakeholderName,Integer withinTime) {
        Query query = em.createQuery("SELECT sdm FROM StakeholderDataModel sdm WHERE sdm.stakeholderName = :sName");
        query.setParameter("sName", stakeholderName);
        List<StakeholderDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        StakeholderDataModel dataModel = resultList.get(0);

        List<StrDblRecord> strDblRecords = dataModel.getStrDblRecords();
        List<Helper_SalesByAge> returnList = new ArrayList<Helper_SalesByAge>();
        for (StrDblRecord r : strDblRecords) {
            if (r.getType().trim().equalsIgnoreCase("S_" + stakeholderName + "SaleAgeGroupW" + withinTime + "M")) {
                returnList.add(new Helper_SalesByAge(r.getNumDouble(), r.getAttribute().trim()));
            }
        }
        return returnList;
    }

    public List<Helper_SalesByCountry> getSSalesByCountry(String stakeholderName,Integer withinTime) {
        Query query = em.createQuery("SELECT sdm FROM StakeholderDataModel sdm WHERE sdm.stakeholderName = :sName");
        query.setParameter("sName", stakeholderName);
        List<StakeholderDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        StakeholderDataModel dataModel = resultList.get(0);

        List<StrDblRecord> strDblRecords = dataModel.getStrDblRecords();
        List<Helper_SalesByCountry> returnList = new ArrayList<Helper_SalesByCountry>();
        for (StrDblRecord r : strDblRecords) {
            if (r.getType().trim().equalsIgnoreCase("S_" + stakeholderName + "SaleCountryW" + withinTime + "M")) {
                returnList.add(new Helper_SalesByCountry(r.getNumDouble(), r.getAttribute().trim()));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }

    public List<Helper_ReservationByAge> getSReservationByAge(String stakeholderName,Integer withinTime) {
        Query query = em.createQuery("SELECT sdm FROM StakeholderDataModel sdm WHERE sdm.stakeholderName = :sName");
        query.setParameter("sName", stakeholderName);
        List<StakeholderDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        StakeholderDataModel dataModel = resultList.get(0);

        List<StrLongRecord> strLongRecords = dataModel.getStrLongRecords();
        List<Helper_ReservationByAge> returnList = new ArrayList<Helper_ReservationByAge>();
        for (StrLongRecord r : strLongRecords) {
            if (r.getType().trim().equalsIgnoreCase("S_" + stakeholderName + "ReservationAgeGroupW" + withinTime + "M")) {
                returnList.add(new Helper_ReservationByAge(r.getNumberLong(), r.getAttribute().trim()));
            }
        }
        return returnList;
    }

    public List<Helper_ReservationByCountry> getSReservationByCountry(String stakeholderName,Integer withinTime) {
        Query query = em.createQuery("SELECT sdm FROM StakeholderDataModel sdm WHERE sdm.stakeholderName = :sName");
        query.setParameter("sName", stakeholderName);
        List<StakeholderDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        StakeholderDataModel dataModel = resultList.get(0);

        List<StrLongRecord> strLongRecords = dataModel.getStrLongRecords();
        List<Helper_ReservationByCountry> returnList = new ArrayList<Helper_ReservationByCountry>();
        for (StrLongRecord r : strLongRecords) {
            if (r.getType().trim().equalsIgnoreCase("S_" + stakeholderName + "ReservationCountryW" + withinTime + "M")) {
                returnList.add(new Helper_ReservationByCountry(r.getNumberLong(), r.getAttribute().trim()));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }

    public List<Helper_MDSCluster> getSAllClusters(String stakeholderName) {
        Query query = em.createQuery("SELECT sdm FROM StakeholderDataModel sdm WHERE sdm.stakeholderName = :sName");
        query.setParameter("sName", stakeholderName);
        List<StakeholderDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        StakeholderDataModel dataModel = resultList.get(0);
        Long[][] cluster = dataModel.getCluster();
        List<Helper_MDSCluster> returnList = new ArrayList<Helper_MDSCluster>();
        String[] countriesArray = dataModel.getCountriesArray();
        String[] ageGroupArray = dataModel.getAgeGroupsArray();
        for (int r = 0; r < cluster.length; r++) {
            for (int c = 0; c < cluster[0].length; c++) {
                returnList.add(new Helper_MDSCluster(countriesArray[r], ageGroupArray[c], cluster[r][c]));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }
    
    public List<Helper_MDSCluster> getSAllClustersW2Y(String stakeholderName) {
        Query query = em.createQuery("SELECT sdm FROM StakeholderDataModel sdm WHERE sdm.stakeholderName = :sName");
        query.setParameter("sName", stakeholderName);
        List<StakeholderDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        StakeholderDataModel dataModel = resultList.get(0);
        Long[][] cluster = dataModel.getClusterW2Y();
        List<Helper_MDSCluster> returnList = new ArrayList<Helper_MDSCluster>();
        String[] countriesArray = dataModel.getCountriesArray();
        String[] ageGroupArray = dataModel.getAgeGroupsArray();
        for (int r = 0; r < cluster.length; r++) {
            for (int c = 0; c < cluster[0].length; c++) {
                returnList.add(new Helper_MDSCluster(countriesArray[r], ageGroupArray[c], cluster[r][c]));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }

    
    public List<Helper_SalesByAge> getTCubeSalesByAge(Integer withinTime) {
        Query query = em.createQuery("SELECT tdm FROM TCubeDataModel tdm");
        List<TCubeDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        TCubeDataModel dataModel = resultList.get(0);

        List<StrDblRecord> strDblRecords = dataModel.getStrDblRecords();
        List<Helper_SalesByAge> returnList = new ArrayList<Helper_SalesByAge>();
        for (StrDblRecord r : strDblRecords) {
            if (r.getType().trim().equalsIgnoreCase("T_SaleAgeGroupW"+withinTime+"M")) {
                returnList.add(new Helper_SalesByAge(r.getNumDouble(), r.getAttribute().trim()));
            }
        }
        return returnList;
    }

    public List<Helper_SalesByCountry> getTCubeSalesByCountry(Integer withinTime) {
        Query query = em.createQuery("SELECT tdm FROM TCubeDataModel tdm");
        List<TCubeDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        TCubeDataModel dataModel = resultList.get(0);

        List<StrDblRecord> strDblRecords = dataModel.getStrDblRecords();
        List<Helper_SalesByCountry> returnList = new ArrayList<Helper_SalesByCountry>();
        for (StrDblRecord r : strDblRecords) {
            if (r.getType().trim().equalsIgnoreCase("T_SaleCountryW"+withinTime+"M")) {
                returnList.add(new Helper_SalesByCountry(r.getNumDouble(), r.getAttribute().trim()));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }

    public List<Helper_ReservationByAge> getTCubeReservationByAge(Integer withinTime) {
        Query query = em.createQuery("SELECT tdm FROM TCubeDataModel tdm");
        List<TCubeDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        TCubeDataModel dataModel = resultList.get(0);

        List<StrLongRecord> strLongRecords = dataModel.getStrLongRecords();
        List<Helper_ReservationByAge> returnList = new ArrayList<Helper_ReservationByAge>();
        for (StrLongRecord r : strLongRecords) {
            if (r.getType().trim().equalsIgnoreCase("T_ReservationAgeGroupW"+withinTime+"M")) {
                returnList.add(new Helper_ReservationByAge(r.getNumberLong(), r.getAttribute().trim()));
            }
        }
        return returnList;
    }

    public List<Helper_ReservationByCountry> getTCubeReservationByCountry(Integer withinTime) {
        Query query = em.createQuery("SELECT tdm FROM TCubeDataModel tdm");
        List<TCubeDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        TCubeDataModel dataModel = resultList.get(0);

        List<StrLongRecord> strLongRecords = dataModel.getStrLongRecords();
        List<Helper_ReservationByCountry> returnList = new ArrayList<Helper_ReservationByCountry>();
        for (StrLongRecord r : strLongRecords) {
            if (r.getType().trim().equalsIgnoreCase("T_ReservationCountryW"+withinTime+"M")) {
                returnList.add(new Helper_ReservationByCountry(r.getNumberLong(), r.getAttribute().trim()));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }

    public List<Helper_MDSCluster> getTCubeAllClusters() {
        Query query = em.createQuery("SELECT tdm FROM TCubeDataModel tdm");
        List<TCubeDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        TCubeDataModel dataModel = resultList.get(0);

        Long[][] cluster = dataModel.getCluster();
        List<Helper_MDSCluster> returnList = new ArrayList<Helper_MDSCluster>();
        String[] countriesArray = dataModel.getCountriesArray();
        String[] ageGroupArray = dataModel.getAgeGroupsArray();
        for (int r = 0; r < cluster.length; r++) {
            for (int c = 0; c < cluster[0].length; c++) {
                returnList.add(new Helper_MDSCluster(countriesArray[r], ageGroupArray[c], cluster[r][c]));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }
    
    public List<Helper_MDSCluster> getTCubeAllClustersW2Y() {
        Query query = em.createQuery("SELECT tdm FROM TCubeDataModel tdm");
        List<TCubeDataModel> resultList = query.getResultList();
        if (resultList == null || resultList.isEmpty()) {
            return null;
        }
        TCubeDataModel dataModel = resultList.get(0);

        Long[][] cluster = dataModel.getClusterW2Y();
        List<Helper_MDSCluster> returnList = new ArrayList<Helper_MDSCluster>();
        String[] countriesArray = dataModel.getCountriesArray();
        String[] ageGroupArray = dataModel.getAgeGroupsArray();
        for (int r = 0; r < cluster.length; r++) {
            for (int c = 0; c < cluster[0].length; c++) {
                returnList.add(new Helper_MDSCluster(countriesArray[r], ageGroupArray[c], cluster[r][c]));
            }
        }
        Collections.sort(returnList, Collections.reverseOrder());
        return returnList;
    }
    //======================MDS Methods End=========================================
}
